/*
Copyright 2010-2011 CumulusCloud
http://cumuluscloud.cc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cumulusCloud.knowledge;

import java.util.logging.Level;
import java.util.logging.Logger;

import cumulusCloud.common.objects.CloudUser;
import cumulusCloud.repository.UserRepository;
import cumulusCloud.repository.folderdb.UserRepositoryFolderDB;
import cumulusCloud.tools.Hashing;


public class UserKnow {
	static private Logger logger = java.util.logging.Logger.getLogger(UserKnow.class.getName());	
	static private UserKnow instance;
	
	public static UserKnow getInstance() {
		if (instance == null) instance = new UserKnow();
		return instance;
	}
	
	private UserRepository userRepository;
	
	private UserKnow() {
		userRepository = new UserRepositoryFolderDB();
	}
	
	public synchronized boolean createUser(CloudUser cu) {
		cu.password = encodePassword(cu.name, cu.password);
		
		logger.log(Level.FINE, "Creating user: {0}", cu);
		
		if (cu.password == null) {
			logger.severe("Password could not be encoded");
			return false;
		}
		
		if (getUser(cu.name) != null) {
			logger.log(Level.FINE, "The user {0} already exists", cu.name);
			return false;
		}
		
		logger.log(Level.FINE, "The user {0} has been created", cu.name);
		return userRepository.saveUser(cu);
	}
	
	public synchronized boolean deleteUser(String user) {
		logger.log(Level.FINE, "Deleting user: {0}", user);
		return userRepository.deleteUser(user);
	}
	
	private String encodePassword(String user, String password) {
		// Salted and Hashed password
		return Hashing.md5("cloud"+user+password);
	}
	
	public CloudUser getUser(String user) {
		logger.log(Level.FINE, "Getting info for user {0}", user);
		CloudUser resultUser = userRepository.getUser(user);

		if (resultUser == null) {
			logger.log(Level.FINE, "User {0} not found", user);
			return null;
		}
		
		return new CloudUser(resultUser);
	}
	
	public boolean isValidCredential(String user, String password) {
		password = encodePassword(user, password);
		
		logger.log(Level.FINE, "Validating credential user: {0} | {1}", new Object[]{user, password});
		
		if (password == null) {
			logger.severe("Password could not be encoded");
			return false;
		}
		
		CloudUser dbUser = getUser(user);
		if (dbUser == null) {
			logger.log(Level.FINE, "The user {0} does not exists", user);
			return false;
		}
		
		if (password.equals(dbUser.password)) {
			logger.log(Level.FINE, "The password is good for {0}", user);
			return true;
		}
		
		logger.log(Level.WARNING, "Wrong password for {0}", user);
		return false;
	}
	
	public CloudUser[] listUsers() {
		return userRepository.getAllUsers();
	}

	public boolean modifyUser(CloudUser previous, CloudUser modified) {
		logger.log(Level.FINE, "Modifying user {0}", previous.name);
		
		// Check if user exists
		if (getUser(previous.name) == null) {
			logger.log(Level.FINE, "The user {0} does not exists", previous.name);
			return false;
		}
		
		// Encode the password if needed
		if (!previous.password.equals(modified.password)) {
			modified.password = encodePassword(modified.name, modified.password);
		}
		
		// Update
		if (!previous.name.equals(modified.name)) {
			userRepository.deleteUser(previous.name);
		}
		
		return userRepository.saveUser(modified);
	}
}
